import { humanFriendlyNumber } from 'lib/utils'

import { CurrencyCode } from '~/queries/schema/schema-general'

// Long name for each currency
export const CURRENCY_SYMBOL_TO_NAME_MAP: Record<CurrencyCode, string> = {
    [CurrencyCode.AED]: 'UAE Dirham',
    [CurrencyCode.AFN]: 'Afghan Afghani',
    [CurrencyCode.ALL]: 'Albanian Lek',
    [CurrencyCode.AMD]: 'Armenian Dram',
    [CurrencyCode.ANG]: 'Antillean Guilder',
    [CurrencyCode.AOA]: 'Angolan Kwanza',
    [CurrencyCode.ARS]: 'Argentine Peso',
    [CurrencyCode.AUD]: 'Australian Dollar',
    [CurrencyCode.AWG]: 'Aruban Florin',
    [CurrencyCode.AZN]: 'Azerbaijani Manat',
    [CurrencyCode.BAM]: 'Bosnia-Herzegovina Convertible Mark',
    [CurrencyCode.BBD]: 'Barbadian Dollar',
    [CurrencyCode.BDT]: 'Bangladeshi Taka',
    [CurrencyCode.BGN]: 'Bulgarian Lev',
    [CurrencyCode.BHD]: 'Bahraini Dinar',
    [CurrencyCode.BIF]: 'Burundian Franc',
    [CurrencyCode.BMD]: 'Bermudan Dollar',
    [CurrencyCode.BND]: 'Brunei Dollar',
    [CurrencyCode.BOB]: 'Bolivian Boliviano',
    [CurrencyCode.BRL]: 'Brazilian Real',
    [CurrencyCode.BSD]: 'Bahamian Dollar',
    [CurrencyCode.BTC]: 'Bitcoin',
    [CurrencyCode.BTN]: 'Bhutanese Ngultrum',
    [CurrencyCode.BWP]: 'Botswanan Pula',
    [CurrencyCode.BYN]: 'Belarusian Ruble',
    [CurrencyCode.BZD]: 'Belize Dollar',
    [CurrencyCode.CAD]: 'Canadian Dollar',
    [CurrencyCode.CDF]: 'Congolese Franc',
    [CurrencyCode.CHF]: 'Swiss Franc',
    [CurrencyCode.CLP]: 'Chilean Peso',
    [CurrencyCode.CNY]: 'Chinese Yuan',
    [CurrencyCode.COP]: 'Colombian Peso',
    [CurrencyCode.CRC]: 'Costa Rican Colón',
    [CurrencyCode.CVE]: 'Cape Verdean Escudo',
    [CurrencyCode.CZK]: 'Czech Republic Koruna',
    [CurrencyCode.DJF]: 'Djiboutian Franc',
    [CurrencyCode.DKK]: 'Danish Krone',
    [CurrencyCode.DOP]: 'Dominican Peso',
    [CurrencyCode.DZD]: 'Algerian Dinar',
    [CurrencyCode.EGP]: 'Egyptian Pound',
    [CurrencyCode.ERN]: 'Eritrean Nakfa',
    [CurrencyCode.ETB]: 'Ethiopian Birr',
    [CurrencyCode.EUR]: 'Euro',
    [CurrencyCode.FJD]: 'Fijian Dollar',
    [CurrencyCode.GBP]: 'British Pound',
    [CurrencyCode.GEL]: 'Georgian Lari',
    [CurrencyCode.GHS]: 'Ghanaian Cedi',
    [CurrencyCode.GIP]: 'Gibraltar Pound',
    [CurrencyCode.GMD]: 'Gambian Dalasi',
    [CurrencyCode.GNF]: 'Guinean Franc',
    [CurrencyCode.GTQ]: 'Guatemalan Quetzal',
    [CurrencyCode.GYD]: 'Guyanaese Dollar',
    [CurrencyCode.HKD]: 'Hong Kong Dollar',
    [CurrencyCode.HNL]: 'Honduran Lempira',
    [CurrencyCode.HRK]: 'Croatian Kuna',
    [CurrencyCode.HTG]: 'Haitian Gourde',
    [CurrencyCode.HUF]: 'Hungarian Forint',
    [CurrencyCode.IDR]: 'Indonesian Rupiah',
    [CurrencyCode.ILS]: 'Israeli New Sheqel',
    [CurrencyCode.INR]: 'Indian Rupee',
    [CurrencyCode.IQD]: 'Iraqi Dinar',
    [CurrencyCode.IRR]: 'Iranian Rial',
    [CurrencyCode.ISK]: 'Icelandic Króna',
    [CurrencyCode.JMD]: 'Jamaican Dollar',
    [CurrencyCode.JOD]: 'Jordanian Dinar',
    [CurrencyCode.JPY]: 'Japanese Yen',
    [CurrencyCode.KES]: 'Kenyan Shilling',
    [CurrencyCode.KGS]: 'Kyrgystani Som',
    [CurrencyCode.KHR]: 'Cambodian Riel',
    [CurrencyCode.KMF]: 'Comorian Franc',
    [CurrencyCode.KRW]: 'South Korean Won',
    [CurrencyCode.KWD]: 'Kuwaiti Dinar',
    [CurrencyCode.KYD]: 'Cayman Islands Dollar',
    [CurrencyCode.KZT]: 'Kazakhstani Tenge',
    [CurrencyCode.LAK]: 'Laotian Kip',
    [CurrencyCode.LBP]: 'Lebanese Pound',
    [CurrencyCode.LKR]: 'Sri Lankan Rupee',
    [CurrencyCode.LRD]: 'Liberian Dollar',
    [CurrencyCode.LTL]: 'Lithuanian Litas',
    [CurrencyCode.LVL]: 'Latvian Lats',
    [CurrencyCode.LSL]: 'Lesotho Loti',
    [CurrencyCode.LYD]: 'Libyan Dinar',
    [CurrencyCode.MAD]: 'Moroccan Dirham',
    [CurrencyCode.MDL]: 'Moldovan Leu',
    [CurrencyCode.MGA]: 'Malagasy Ariary',
    [CurrencyCode.MKD]: 'Macedonian Denar',
    [CurrencyCode.MMK]: 'Myanma Kyat',
    [CurrencyCode.MNT]: 'Mongolian Tugrik',
    [CurrencyCode.MOP]: 'Macanese Pataca',
    [CurrencyCode.MRU]: 'Mauritanian Ouguiya',
    [CurrencyCode.MTL]: 'Maltese Lira',
    [CurrencyCode.MUR]: 'Mauritian Rupee',
    [CurrencyCode.MVR]: 'Maldivian Rufiyaa',
    [CurrencyCode.MWK]: 'Malawian Kwacha',
    [CurrencyCode.MXN]: 'Mexican Peso',
    [CurrencyCode.MYR]: 'Malaysian Ringgit',
    [CurrencyCode.MZN]: 'Mozambican Metical',
    [CurrencyCode.NAD]: 'Namibian Dollar',
    [CurrencyCode.NGN]: 'Nigerian Naira',
    [CurrencyCode.NIO]: 'Nicaraguan Córdoba',
    [CurrencyCode.NOK]: 'Norwegian Krone',
    [CurrencyCode.NPR]: 'Nepalese Rupee',
    [CurrencyCode.NZD]: 'New Zealand Dollar',
    [CurrencyCode.OMR]: 'Omani Rial',
    [CurrencyCode.PAB]: 'Panamanian Balboa',
    [CurrencyCode.PEN]: 'Peruvian Nuevo Sol',
    [CurrencyCode.PGK]: 'Papua New Guinean Kina',
    [CurrencyCode.PHP]: 'Philippine Peso',
    [CurrencyCode.PKR]: 'Pakistani Rupee',
    [CurrencyCode.PLN]: 'Polish Zloty',
    [CurrencyCode.PYG]: 'Paraguayan Guarani',
    [CurrencyCode.QAR]: 'Qatari Rial',
    [CurrencyCode.RON]: 'Romanian Leu',
    [CurrencyCode.RSD]: 'Serbian Dinar',
    [CurrencyCode.RUB]: 'Russian Ruble',
    [CurrencyCode.RWF]: 'Rwandan Franc',
    [CurrencyCode.SAR]: 'Saudi Riyal',
    [CurrencyCode.SBD]: 'Solomon Islands Dollar',
    [CurrencyCode.SCR]: 'Seychellois Rupee',
    [CurrencyCode.SDG]: 'Sudanese Pound',
    [CurrencyCode.SEK]: 'Swedish Krona',
    [CurrencyCode.SGD]: 'Singapore Dollar',
    [CurrencyCode.SRD]: 'Surinamese Dollar',
    [CurrencyCode.SSP]: 'South Sudanese Pound',
    [CurrencyCode.STN]: 'São Tomé and Príncipe Dobra',
    [CurrencyCode.SYP]: 'Syrian Pound',
    [CurrencyCode.SZL]: 'Swazi Lilangeni',
    [CurrencyCode.THB]: 'Thai Baht',
    [CurrencyCode.TJS]: 'Tajikistani Somoni',
    [CurrencyCode.TMT]: 'Turkmenistani Manat',
    [CurrencyCode.TND]: 'Tunisian Dinar',
    [CurrencyCode.TOP]: "Tongan Pa'anga",
    [CurrencyCode.TRY]: 'Turkish Lira',
    [CurrencyCode.TTD]: 'Trinidad and Tobago Dollar',
    [CurrencyCode.TWD]: 'New Taiwan Dollar',
    [CurrencyCode.TZS]: 'Tanzanian Shilling',
    [CurrencyCode.UAH]: 'Ukrainian Hryvnia',
    [CurrencyCode.UGX]: 'Ugandan Shilling',
    [CurrencyCode.USD]: 'American Dollar',
    [CurrencyCode.UYU]: 'Uruguayan Peso',
    [CurrencyCode.UZS]: 'Uzbekistan Som',
    [CurrencyCode.VES]: 'Venezuelan Bolívar Soberano',
    [CurrencyCode.VND]: 'Vietnamese Dong',
    [CurrencyCode.VUV]: 'Vanuatu Vatu',
    [CurrencyCode.WST]: 'Samoan Tala',
    [CurrencyCode.XAF]: 'CFA Franc BEAC',
    [CurrencyCode.XCD]: 'East Caribbean Dollar',
    [CurrencyCode.XOF]: 'CFA Franc BCEAO',
    [CurrencyCode.XPF]: 'CFP Franc',
    [CurrencyCode.YER]: 'Yemeni Rial',
    [CurrencyCode.ZAR]: 'South African Rand',
    [CurrencyCode.ZMW]: 'Zambian Kwacha',
}

// Flag (or emoji in some cases) for each individually supported currency
export const CURRENCY_SYMBOL_TO_EMOJI_MAP: Record<CurrencyCode, string> = {
    [CurrencyCode.AED]: '🇦🇪',
    [CurrencyCode.AFN]: '🇦🇫',
    [CurrencyCode.ALL]: '🇦🇱',
    [CurrencyCode.AMD]: '🇦🇲',
    [CurrencyCode.ANG]: '🇧🇶',
    [CurrencyCode.AOA]: '🇦🇴',
    [CurrencyCode.ARS]: '🇦🇷',
    [CurrencyCode.AUD]: '🇦🇺',
    [CurrencyCode.AWG]: '🇦🇼',
    [CurrencyCode.AZN]: '🇦🇿',
    [CurrencyCode.BAM]: '🇧🇦',
    [CurrencyCode.BBD]: '🇧🇧',
    [CurrencyCode.BDT]: '🇧🇩',
    [CurrencyCode.BGN]: '🇧🇬',
    [CurrencyCode.BHD]: '🇧🇭',
    [CurrencyCode.BIF]: '🇧🇮',
    [CurrencyCode.BMD]: '🇧🇲',
    [CurrencyCode.BND]: '🇧🇳',
    [CurrencyCode.BOB]: '🇧🇴',
    [CurrencyCode.BRL]: '🇧🇷',
    [CurrencyCode.BSD]: '🇧🇸',
    [CurrencyCode.BTC]: ' ₿  ', // Non-breaking whitespace to align with other currencies in the UI
    [CurrencyCode.BTN]: '🇧🇹',
    [CurrencyCode.BWP]: '🇧🇼',
    [CurrencyCode.BYN]: '🇧🇾',
    [CurrencyCode.BZD]: '🇧🇿',
    [CurrencyCode.CAD]: '🇨🇦',
    [CurrencyCode.CDF]: '🇨🇩',
    [CurrencyCode.CHF]: '🇨🇭',
    [CurrencyCode.CLP]: '🇨🇱',
    [CurrencyCode.CNY]: '🇨🇳',
    [CurrencyCode.COP]: '🇨🇴',
    [CurrencyCode.CRC]: '🇨🇷',
    [CurrencyCode.CVE]: '🇨🇻',
    [CurrencyCode.CZK]: '🇨🇿',
    [CurrencyCode.DJF]: '🇩🇯',
    [CurrencyCode.DKK]: '🇩🇰',
    [CurrencyCode.DOP]: '🇩🇴',
    [CurrencyCode.DZD]: '🇩🇿',
    [CurrencyCode.EGP]: '🇪🇬',
    [CurrencyCode.ERN]: '🇪🇷',
    [CurrencyCode.ETB]: '🇪🇹',
    [CurrencyCode.EUR]: '🇪🇺',
    [CurrencyCode.FJD]: '🇫🇯',
    [CurrencyCode.GBP]: '🇬🇧',
    [CurrencyCode.GEL]: '🇬🇪',
    [CurrencyCode.GHS]: '🇬🇭',
    [CurrencyCode.GIP]: '🇬🇮',
    [CurrencyCode.GMD]: '🇬🇲',
    [CurrencyCode.GNF]: '🇬🇳',
    [CurrencyCode.GTQ]: '🇬🇹',
    [CurrencyCode.GYD]: '🇬🇾',
    [CurrencyCode.HKD]: '🇭🇰',
    [CurrencyCode.HNL]: '🇭🇳',
    [CurrencyCode.HRK]: '🇭🇷',
    [CurrencyCode.HTG]: '🇭🇹',
    [CurrencyCode.HUF]: '🇭🇺',
    [CurrencyCode.IDR]: '🇮🇩',
    [CurrencyCode.ILS]: '🇮🇱',
    [CurrencyCode.INR]: '🇮🇳',
    [CurrencyCode.IQD]: '🇮🇶',
    [CurrencyCode.IRR]: '🇮🇷',
    [CurrencyCode.ISK]: '🇮🇸',
    [CurrencyCode.JMD]: '🇯🇲',
    [CurrencyCode.JOD]: '🇯🇴',
    [CurrencyCode.JPY]: '🇯🇵',
    [CurrencyCode.KES]: '🇰🇪',
    [CurrencyCode.KGS]: '🇰🇬',
    [CurrencyCode.KHR]: '🇰🇭',
    [CurrencyCode.KMF]: '🇰🇲',
    [CurrencyCode.KRW]: '🇰🇷',
    [CurrencyCode.KWD]: '🇰🇼',
    [CurrencyCode.KYD]: '🇰🇾',
    [CurrencyCode.KZT]: '🇰🇿',
    [CurrencyCode.LAK]: '🇱🇦',
    [CurrencyCode.LBP]: '🇱🇧',
    [CurrencyCode.LKR]: '🇱🇰',
    [CurrencyCode.LRD]: '🇱🇷',
    [CurrencyCode.LTL]: '🇱🇹',
    [CurrencyCode.LVL]: '🇱🇻',
    [CurrencyCode.LSL]: '🇱🇸',
    [CurrencyCode.LYD]: '🇱🇾',
    [CurrencyCode.MAD]: '🇲🇦',
    [CurrencyCode.MDL]: '🇲🇩',
    [CurrencyCode.MGA]: '🇲🇬',
    [CurrencyCode.MKD]: '🇲🇰',
    [CurrencyCode.MMK]: '🇲🇲',
    [CurrencyCode.MNT]: '🇲🇳',
    [CurrencyCode.MOP]: '🇲🇴',
    [CurrencyCode.MRU]: '🇲🇷',
    [CurrencyCode.MTL]: '🇲🇹',
    [CurrencyCode.MUR]: '🇲🇺',
    [CurrencyCode.MVR]: '🇲🇻',
    [CurrencyCode.MWK]: '🇲🇼',
    [CurrencyCode.MXN]: '🇲🇽',
    [CurrencyCode.MYR]: '🇲🇾',
    [CurrencyCode.MZN]: '🇲🇿',
    [CurrencyCode.NAD]: '🇳🇦',
    [CurrencyCode.NGN]: '🇳🇬',
    [CurrencyCode.NIO]: '🇳🇮',
    [CurrencyCode.NOK]: '🇳🇴',
    [CurrencyCode.NPR]: '🇳🇵',
    [CurrencyCode.NZD]: '🇳🇿',
    [CurrencyCode.OMR]: '🇴🇲',
    [CurrencyCode.PAB]: '🇵🇦',
    [CurrencyCode.PEN]: '🇵🇪',
    [CurrencyCode.PGK]: '🇵🇬',
    [CurrencyCode.PHP]: '🇵🇭',
    [CurrencyCode.PKR]: '🇵🇰',
    [CurrencyCode.PLN]: '🇵🇱',
    [CurrencyCode.PYG]: '🇵🇾',
    [CurrencyCode.QAR]: '🇶🇦',
    [CurrencyCode.RON]: '🇷🇴',
    [CurrencyCode.RSD]: '🇷🇸',
    [CurrencyCode.RUB]: '🇷🇺',
    [CurrencyCode.RWF]: '🇷🇼',
    [CurrencyCode.SAR]: '🇸🇦',
    [CurrencyCode.SBD]: '🇸🇧',
    [CurrencyCode.SCR]: '🇸🇨',
    [CurrencyCode.SDG]: '🇸🇩',
    [CurrencyCode.SEK]: '🇸🇪',
    [CurrencyCode.SGD]: '🇸🇬',
    [CurrencyCode.SRD]: '🇸🇷',
    [CurrencyCode.SSP]: '🇸🇸',
    [CurrencyCode.STN]: '🇸🇹',
    [CurrencyCode.SYP]: '🇸🇾',
    [CurrencyCode.SZL]: '🇸🇿',
    [CurrencyCode.THB]: '🇹🇭',
    [CurrencyCode.TJS]: '🇹🇯',
    [CurrencyCode.TMT]: '🇹🇲',
    [CurrencyCode.TND]: '🇹🇳',
    [CurrencyCode.TOP]: '🇹🇴',
    [CurrencyCode.TRY]: '🇹🇷',
    [CurrencyCode.TTD]: '🇹🇹',
    [CurrencyCode.TWD]: '🇹🇼',
    [CurrencyCode.TZS]: '🇹🇿',
    [CurrencyCode.UAH]: '🇺🇦',
    [CurrencyCode.UGX]: '🇺🇬',
    [CurrencyCode.USD]: '🇺🇸',
    [CurrencyCode.UYU]: '🇺🇾',
    [CurrencyCode.UZS]: '🇺🇿',
    [CurrencyCode.VES]: '🇻🇪',
    [CurrencyCode.VND]: '🇻🇳',
    [CurrencyCode.VUV]: '🇻🇺',
    [CurrencyCode.WST]: '🇼🇸',
    [CurrencyCode.XAF]: '🌍', // Central Africa currency, using Africa+Europe globe emoji
    [CurrencyCode.XCD]: '🌎', // East Caribbean Dollar, using Americas globe emoji
    [CurrencyCode.XOF]: '🌍', // West Africa currency, using Africa+Europe globe emoji
    [CurrencyCode.XPF]: '🌏', // French ultramarine territories in Oceania, using Asia+Oceania globe emoji
    [CurrencyCode.YER]: '🇾🇪',
    [CurrencyCode.ZAR]: '🇿🇦',
    [CurrencyCode.ZMW]: '🇿🇲',
}

// These currencies are disabled as default currencies for one reason or another
export const DISABLED_CURRENCIES: { [key in CurrencyCode]?: string } = {
    [CurrencyCode.HRK]: 'Replaced by the Euro on Jan 1st 2023',
    [CurrencyCode.LTL]: 'Replaced by the Euro on Jan 1st 2015',
    [CurrencyCode.LVL]: 'Replaced by the Euro on Jan 1st 2014',
    [CurrencyCode.MTL]: 'Replaced by the Euro on Jan 1st 2008',
}

/** Get the currency symbol and whether it's a prefix or suffix.
 *
 * @param currency - The currency to get the symbol for.
 * @returns The currency symbol and whether it's a prefix or suffix.
 *
 * Example:
 * getCurrencySymbol('USD') // { symbol: '$', isPrefix: true }
 * getCurrencySymbol('GBP') // { symbol: '£', isPrefix: true }
 */
export const getCurrencySymbol = (currency: string): { symbol: string; isPrefix: boolean } => {
    const formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: currency,
    })
    const parts = formatter.formatToParts(0)
    const symbol = parts.find((part) => part.type === 'currency')?.value

    const isPrefix = symbol ? parts[0].type === 'currency' : true

    return { symbol: symbol ?? currency, isPrefix }
}

/** Format a number as a currency string, including the currency symbol.
 *
 * @param amount - The amount to format.
 * @param currency - The currency to format the amount in.
 * @returns The formatted currency string.
 *
 * Example:
 * formatCurrency(1234.56, 'USD') // '$1,234.56'
 * formatCurrency(1234.56, 'EUR') // '€1,234.56'
 */
export const formatCurrency = (amount: number, currency: CurrencyCode): string => {
    const { symbol, isPrefix } = getCurrencySymbol(currency)
    return `${isPrefix ? symbol : ''}${humanFriendlyNumber(amount, 2, 2)}${isPrefix ? '' : ' ' + symbol}`
}

export const DEFAULT_CURRENCY = CurrencyCode.USD

// These are the currencies that are most important to show first because they're used by the most customers.
// Check our web analytics dashboard for the most popular countries from our visitors.
export const IMPORTANT_CURRENCIES: CurrencyCode[] = [
    CurrencyCode.USD,
    CurrencyCode.EUR,
    CurrencyCode.GBP,
    CurrencyCode.CAD,
    CurrencyCode.INR,
    CurrencyCode.CNY,
    CurrencyCode.BRL,
]

// All the other currencies, sorted by their "long name" in alphabetical order.
export const OTHER_CURRENCIES: CurrencyCode[] = (
    Object.keys(CurrencyCode).filter(
        (currency) => !IMPORTANT_CURRENCIES.includes(currency as CurrencyCode)
    ) as CurrencyCode[]
).sort((a, b) => {
    return CURRENCY_SYMBOL_TO_NAME_MAP[a].localeCompare(CURRENCY_SYMBOL_TO_NAME_MAP[b])
})
